# -*- coding: utf-8 -*-
"""
表选择界面
"""
from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QGridLayout,
                            QLabel, QPushButton, QListWidget, QListWidgetItem,
                            QCheckBox, QGroupBox, QMessageBox, QTableWidget,
                            QTableWidgetItem, QHeaderView, QSplitter, QTextEdit)
from PyQt5.QtCore import Qt, pyqtSignal
from PyQt5.QtGui import QFont
from core.dict_extractor import DictExtractor

class TableSelectionWidget(QWidget):
    """表选择界面"""
    
    tables_selected = pyqtSignal(list)
    
    def __init__(self, dict_extractor: DictExtractor):
        super().__init__()
        self.dict_extractor = dict_extractor
        self.all_tables = []
        self.selected_tables = []
        
        self.init_ui()
    
    def init_ui(self):
        """初始化界面"""
        layout = QVBoxLayout(self)
        
        # 创建分割器
        splitter = QSplitter(Qt.Horizontal)
        layout.addWidget(splitter)
        
        # 左侧：表列表
        self.create_table_list(splitter)
        
        # 右侧：表预览
        self.create_table_preview(splitter)
        
        # 设置分割器比例
        splitter.setSizes([400, 600])
    
    def create_table_list(self, parent):
        """创建表列表区域"""
        table_widget = QWidget()
        table_layout = QVBoxLayout(table_widget)
        
        # 表选择组
        table_group = QGroupBox("表选择")
        table_group_layout = QVBoxLayout(table_group)
        
        # 操作按钮
        button_layout = QHBoxLayout()
        
        self.select_all_button = QPushButton("全选")
        self.select_all_button.clicked.connect(self.select_all_tables)
        button_layout.addWidget(self.select_all_button)
        
        self.select_none_button = QPushButton("全不选")
        self.select_none_button.clicked.connect(self.select_none_tables)
        button_layout.addWidget(self.select_none_button)
        
        self.refresh_button = QPushButton("刷新")
        self.refresh_button.clicked.connect(self.refresh_tables)
        button_layout.addWidget(self.refresh_button)
        
        table_group_layout.addLayout(button_layout)
        
        # 表列表
        self.table_list = QListWidget()
        self.table_list.itemChanged.connect(self.on_table_selection_changed)
        self.table_list.itemClicked.connect(self.on_table_clicked)
        table_group_layout.addWidget(self.table_list)
        
        # 统计信息
        self.table_count_label = QLabel("表总数: 0")
        table_group_layout.addWidget(self.table_count_label)
        
        self.selected_count_label = QLabel("已选择: 0")
        table_group_layout.addWidget(self.selected_count_label)
        
        table_layout.addWidget(table_group)
        parent.addWidget(table_widget)
    
    def create_table_preview(self, parent):
        """创建表预览区域"""
        preview_widget = QWidget()
        preview_layout = QVBoxLayout(preview_widget)
        
        # 表预览组
        preview_group = QGroupBox("表结构预览")
        preview_group_layout = QVBoxLayout(preview_group)
        
        # 表信息
        self.table_info_label = QLabel("请选择一个表进行预览")
        self.table_info_label.setStyleSheet("font-weight: bold; color: #666;")
        preview_group_layout.addWidget(self.table_info_label)
        
        # 字段信息表格
        self.field_table = QTableWidget()
        self.field_table.setColumnCount(6)
        self.field_table.setHorizontalHeaderLabels([
            "字段名", "数据类型", "是否为空", "主键", "默认值", "字段注释"
        ])
        self.field_table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.field_table.setAlternatingRowColors(True)
        preview_group_layout.addWidget(self.field_table)
        
        # 索引信息
        self.index_label = QLabel("索引信息:")
        self.index_label.setStyleSheet("font-weight: bold; margin-top: 10px;")
        preview_group_layout.addWidget(self.index_label)
        
        self.index_text = QTextEdit()
        self.index_text.setMaximumHeight(150)
        self.index_text.setReadOnly(True)
        preview_group_layout.addWidget(self.index_text)
        
        preview_layout.addWidget(preview_group)
        parent.addWidget(preview_widget)
    
    def refresh_tables(self):
        """刷新表列表"""
        try:
            # 获取所有表
            self.all_tables = self.dict_extractor.mysql_connector.get_tables()
            
            # 清空列表
            self.table_list.clear()
            self.selected_tables = []
            
            # 添加表到列表
            for table_name in self.all_tables:
                item = QListWidgetItem()
                item.setText(table_name)
                item.setFlags(item.flags() | Qt.ItemIsUserCheckable)
                item.setCheckState(Qt.Unchecked)
                item.setData(Qt.UserRole, table_name)
                self.table_list.addItem(item)
            
            # 更新统计信息
            self.update_table_count()
            
            # 清空预览
            self.clear_preview()
            
            # 发送选择变化信号
            self.tables_selected.emit([])
            
        except Exception as e:
            QMessageBox.critical(self, "刷新失败", f"刷新表列表失败:\n{str(e)}")
    
    def select_all_tables(self):
        """全选表"""
        total_count = self.table_list.count()
        if total_count == 0:
            return
        
        # 如果表数量很多，显示提示信息
        if total_count > 100:
            from PyQt5.QtWidgets import QApplication
            QApplication.setOverrideCursor(Qt.WaitCursor)
        
        try:
            # 临时断开信号连接，避免大量信号处理导致界面无响应
            self.table_list.itemChanged.disconnect()
            
            # 批量处理，每100个表处理一次，避免界面卡顿
            batch_size = 100
            for start_idx in range(0, total_count, batch_size):
                end_idx = min(start_idx + batch_size, total_count)
                for i in range(start_idx, end_idx):
                    item = self.table_list.item(i)
                    if item:
                        item.setCheckState(Qt.Checked)
                
                # 处理事件队列，保持界面响应
                from PyQt5.QtWidgets import QApplication
                QApplication.processEvents()
        finally:
            # 重新连接信号
            self.table_list.itemChanged.connect(self.on_table_selection_changed)
            
            # 恢复鼠标光标
            if total_count > 100:
                QApplication.restoreOverrideCursor()
        
        # 手动调用一次选择变化处理
        self.on_table_selection_changed()
    
    def select_none_tables(self):
        """全不选表"""
        total_count = self.table_list.count()
        if total_count == 0:
            return
        
        # 如果表数量很多，显示提示信息
        if total_count > 100:
            from PyQt5.QtWidgets import QApplication
            QApplication.setOverrideCursor(Qt.WaitCursor)
        
        try:
            # 临时断开信号连接，避免大量信号处理导致界面无响应
            self.table_list.itemChanged.disconnect()
            
            # 批量处理，每100个表处理一次，避免界面卡顿
            batch_size = 100
            for start_idx in range(0, total_count, batch_size):
                end_idx = min(start_idx + batch_size, total_count)
                for i in range(start_idx, end_idx):
                    item = self.table_list.item(i)
                    if item:
                        item.setCheckState(Qt.Unchecked)
                
                # 处理事件队列，保持界面响应
                from PyQt5.QtWidgets import QApplication
                QApplication.processEvents()
        finally:
            # 重新连接信号
            self.table_list.itemChanged.connect(self.on_table_selection_changed)
            
            # 恢复鼠标光标
            if total_count > 100:
                QApplication.restoreOverrideCursor()
        
        # 手动调用一次选择变化处理
        self.on_table_selection_changed()
    
    def on_table_selection_changed(self):
        """表选择变化处理"""
        # 更新选中表列表
        self.selected_tables = []
        total_count = self.table_list.count()
        
        # 批量处理，避免界面卡顿
        batch_size = 200
        for start_idx in range(0, total_count, batch_size):
            end_idx = min(start_idx + batch_size, total_count)
            for i in range(start_idx, end_idx):
                item = self.table_list.item(i)
                if item and item.checkState() == Qt.Checked:
                    self.selected_tables.append(item.data(Qt.UserRole))
            
            # 处理事件队列，保持界面响应
            if total_count > 100:  # 只有在表数量较多时才处理事件
                from PyQt5.QtWidgets import QApplication
                QApplication.processEvents()
        
        # 更新统计信息
        self.update_selected_count()
        
        # 发送选择变化信号
        self.tables_selected.emit(self.selected_tables.copy())
    
    def on_table_clicked(self, item):
        """表名点击处理"""
        if item:
            table_name = item.data(Qt.UserRole)
            if table_name:
                # 更新表信息标签，显示正在加载
                self.table_info_label.setText(f"正在加载表 {table_name} 的结构信息...")
                self.field_table.setRowCount(0)
                self.index_text.clear()
                
                # 显示表预览
                self.show_table_preview(table_name)
    
    def update_table_count(self):
        """更新表总数"""
        self.table_count_label.setText(f"表总数: {len(self.all_tables)}")
    
    def update_selected_count(self):
        """更新已选择数量"""
        self.selected_count_label.setText(f"已选择: {len(self.selected_tables)}")
    
    def clear_tables(self):
        """清空表列表"""
        self.table_list.clear()
        self.all_tables = []
        self.selected_tables = []
        self.update_table_count()
        self.update_selected_count()
        self.clear_preview()
    
    def clear_preview(self):
        """清空预览"""
        self.table_info_label.setText("请选择一个表进行预览")
        self.field_table.setRowCount(0)
        self.index_text.clear()
    
    def show_table_preview(self, table_name: str):
        """显示表预览"""
        try:
            # 获取表预览信息
            preview = self.dict_extractor.get_table_preview(table_name)
            if not preview:
                self.table_info_label.setText(f"无法获取表 {table_name} 的结构信息")
                self.field_table.setRowCount(0)
                self.index_text.setText("获取表结构信息失败")
                return
            
            # 更新表信息
            info_text = f"表: {preview['table_name']}"
            if preview['table_comment']:
                info_text += f" - {preview['table_comment']}"
            info_text += f" (字段数: {preview['column_count']}, 索引数: {preview['index_count']})"
            self.table_info_label.setText(info_text)
            
            # 更新字段信息表格
            self.field_table.setRowCount(len(preview['columns_preview']))
            for row, column in enumerate(preview['columns_preview']):
                self.field_table.setItem(row, 0, QTableWidgetItem(column['name']))
                self.field_table.setItem(row, 1, QTableWidgetItem(column['type']))
                self.field_table.setItem(row, 2, QTableWidgetItem("是" if column['nullable'] else "否"))
                self.field_table.setItem(row, 3, QTableWidgetItem("是" if column['key'] == 'PRI' else "否"))
                self.field_table.setItem(row, 4, QTableWidgetItem(str(column.get('default', ''))))
                self.field_table.setItem(row, 5, QTableWidgetItem(column['comment']))
            
            # 更新索引信息
            if preview['indexes_preview']:
                index_text = ""
                for index in preview['indexes_preview']:
                    index_text += f"• {index['name']} ({index['type']})"
                    if index['unique']:
                        index_text += " [唯一]"
                    index_text += f": {index['columns']}\n"
                self.index_text.setText(index_text)
            else:
                self.index_text.setText("无索引")
                
        except Exception as e:
            QMessageBox.critical(self, "预览失败", f"获取表预览失败:\n{str(e)}")
    
    def get_selected_tables(self) -> list:
        """获取选中的表"""
        return self.selected_tables.copy()
    
    def set_selected_tables(self, table_names: list):
        """设置选中的表"""
        # 清空当前选择
        for i in range(self.table_list.count()):
            item = self.table_list.item(i)
            item.setCheckState(Qt.Unchecked)
        
        # 设置新的选择
        for table_name in table_names:
            for i in range(self.table_list.count()):
                item = self.table_list.item(i)
                if item.data(Qt.UserRole) == table_name:
                    item.setCheckState(Qt.Checked)
                    break
        
        self.on_table_selection_changed()
